<?php
class nl_file_encode_yunshi extends nn_public_return
{
    /**
     * 视频参数
     * @var unknown
     */
    public $arr_video_params = array(
        'video_aspect'=>'16:9',
        'bframes'=>'3',
        'iframe_interval'=>'50',
        'interlaced'=>'disable',
        'level'=>'40',
        'max_v_bitrate'=>2355200,
        'profile'=>'high',
        'rc_method'=>'vbr',
        'ref_count'=>'3',
        'v_type'=>'h264',
        'scenecut_detect'=>'enable',
        'v_bitrate'=>2232320,
        'v_pass'=>'1',
        'video_open_gop'=>'1',
        'video_quality'=>'slow',
        'output_size'=>'1920x1080',
        'fps'=>'auto',
    );
    
    /**
     * 音频参数
     * @var unknown
     */
    public $arr_audio_params = array(
        'a_bitrate'=>'192000',
        'channels'=>'2',
        'a_type'=>'ac3',
        'sample_rate'=>'48000',
    );
    /**
     * 转码负载均衡
     * @var unknown
     */
    public $flag_loadbalance_encode = FALSE;
    /**
     * 队列数据
     * @var unknown
     */
	public $data_queue = null;
	/**
	 * 模板数据  带请求地址
	 * @var unknown
	 */
	public $data_model = null;
	/**
	 * 其他请求参数
	 * @var unknown
	 */
	public $arr_params = null;
	/**
	 * 请求地址  带 点播、直播
	 * @var unknown
	 */
	public $request_url = null;
    /**
     * 转码后的文件地址（片源文件、抽帧图片）
     * @var unknown
     */
	public $encode_file_url = null;
	
	public $curl_way = null;
    
    public function __construct($obj_dc,$data_queue=null,$data_model=null,$arr_sp_config,$sp_id,$arr_params=null)
    {
        if(isset($data_model['nns_video_config']))
        {
            $data_model['nns_video_config'] = $this->is_json($data_model['nns_video_config']) ? json_decode($data_model['nns_video_config'],true) : null;
        }
        if(isset($data_model['nns_audio_config']))
        {
            $data_model['nns_audio_config'] = $this->is_json($data_model['nns_audio_config']) ? json_decode($data_model['nns_audio_config'],true) : null;
        }
        $this->obj_dc = $obj_dc;
        $this->data_queue = $data_queue;
        $this->data_model = $data_model;
        $this->arr_params = $arr_params;
        $this->arr_sp_config = $arr_sp_config;
        $this->sp_id = $sp_id;
    }
    
    /**
     * 初始化转码配置
     * @return array('ret'=>'状态码','reason'=>'原因','data'=>'数据')
     */
    public function init($str_type='0')
    {
        $this->encode_file_url = (isset($this->data_queue['nns_file_url']) && strlen($this->data_queue['nns_file_url'])>0 && $this->is_json($this->data_queue['nns_file_url'])) ? json_decode($this->data_queue['nns_file_url'],true) : null;
        if(isset($this->arr_sp_config[$this->sp_id]['nns_config']['transcode_load_balance_encode']) && $this->arr_sp_config[$this->sp_id]['nns_config']['transcode_load_balance_encode'] == '1' && $str_type =='0' && !empty($this->arr_params) && is_array($this->arr_params))
        {
            $this->request_url['video'] = $this->arr_params['nns_api_url'];
            $this->request_url['loadbalance_id'] = $this->arr_params['nns_id'];
        }
        else
        {
            $this->request_url = (isset($this->data_model['manufacturer_api_addr']) && strlen($this->data_model['manufacturer_api_addr'])>0 && $this->is_json($this->data_model['manufacturer_api_addr'])) ? json_decode($this->data_model['manufacturer_api_addr'],true) : null;
            $this->request_url = (is_array($this->request_url) && !empty($this->request_url)) ? $this->request_url : null;
            $this->request_url['loadbalance_id'] = '59e06461336ef9164ad3ccc852ad7f2f';
        }
        $this->encode_file_url = (is_array($this->encode_file_url) && !empty($this->encode_file_url)) ? $this->encode_file_url : null;
        $clip_file_encode_way = (isset($this->arr_sp_config[$this->sp_id]['nns_config']['clip_file_encode_way']) && strlen($this->arr_sp_config[$this->sp_id]['nns_config']['clip_file_encode_way']) >0) ? strtolower($this->arr_sp_config[$this->sp_id]['nns_config']['clip_file_encode_way']) : '';
        $clip_file_encode_way = strtolower($clip_file_encode_way);
        $this->curl_way = in_array($clip_file_encode_way, array('post','get')) ? $clip_file_encode_way : 'post';
    }
       
    
    public function set_task()
    {
        switch ($this->data_queue['nns_type'])
        {
            case '1':
                $this->init('1');
                return $this->set_task_live();
            case '2':
                $this->init('0');
                return $this->set_task_live_to_media();
            default:
                $this->init('0');
                return $this->set_task_media();                
        }
    }
    
    /**
     * 直播转码
     */
    public function set_task_live()
    {
        if(strlen($this->request_url['live']) <1)
        {
            return $this->__return_data(1,'转码请求地址request_url配置为空:'.$this->request_url);
        }
        $result_media = nl_live_media::query_by_id($this->obj_dc, $this->data_queue['nns_in_media_id']);
        if($result_media['ret'] !=0)
        {
            return $result_media;
        }
        $result_media_out = nl_live_media::query_by_id($this->obj_dc, $this->data_queue['nns_out_media_id']);
        if($result_media_out['ret'] !=0)
        {
            return $result_media_out;
        }
        if(!isset($result_media['data_info']['nns_url']) || strlen($result_media['data_info']['nns_url'])<1)
        {
            return $this->__return_data(1,'查询的原始片源没有片源路径');
        }
        $out_bitrate = (int)$this->data_model['nns_output_bitrate'] > 0 ? (int)$this->data_model['nns_output_bitrate']*1024 : 4000*1024;
        $inout_xml ='<?xml version="1.0" encoding="UTF-8"?>';
        $inout_xml.='<message module="URS" version="1.0">';
        $inout_xml.=    '<header action="REQUEST" command="ENCODER_LIVE_START" />';
        $inout_xml.=    '<body>';
        $inout_xml.=        '<task id="'.$this->data_queue['nns_integer_id'].'" mode="ONLINE" source-type="IP" program-no="'.$result_media_out['nns_integer_id'].'" ca="" ip-source-url="'.$result_media['data_info']['nns_url'].'">';
        $inout_xml.=        '<encode-params>';
        $inout_xml.=            '<system-params system-type="ts" ts-ip="192.168.1.26" ts-port="6001"/>';
        $inout_xml.=            '<video-params video-codec="h264" rcmode="Onepass" video-width="1920" video-height="1080" video-frame-rate="25" video-bitrate="'.$out_bitrate.'" video-b-frame-num="5" video-key-frame-interval="0.2" />';
        $inout_xml.=            '<audio-params audio-codec="aaclc" audio-channels="2" audio-sample-rate="32000" audio-channel-mode="allchannels" audio-bitrate-bps="16000"/>';
        $inout_xml.=            '<video-codec-params h264-profile="main" h264-level="30"/>';
        $inout_xml.=        '</encode-params>';
        if(isset($this->encode_file_url['drawing_frame']) && is_array($this->encode_file_url['drawing_frame']) && !empty($this->encode_file_url['drawing_frame']))
        {
            if(!isset($this->arr_sp_config[$this->sp_id]['nns_config']['drawing_frame_addr_output']) || strlen($this->arr_sp_config[$this->sp_id]['nns_config']['drawing_frame_addr_output']) <1)
            {
                return $this->__return_data(1,'抽帧图片img_ftp输入FTP配置为空:'.$this->arr_sp_config[$this->sp_id]['nns_config']['img_ftp']);
            }
            $ftp_drawing_frame_url = trim(rtrim(rtrim($this->arr_sp_config[$this->sp_id]['nns_config']['drawing_frame_addr_output'],'/'),'\\'));
            $this->data_model['nns_drawing_rule'] = (int)$this->data_model['nns_drawing_rule'] > 0 ? (int)$this->data_model['nns_drawing_rule'] : 20;
            $i = 0;
            foreach ($this->encode_file_url['drawing_frame'] as $drawing_frame_val)
            {
                $i++;
                if($i > 1)
                {
                    break;
                }
                $drawing_frame_val = trim(ltrim(ltrim($drawing_frame_val,'/'),'\\'));
                if(strlen($drawing_frame_val) <1)
                {
                    continue;
                }
                $drawing_frame_url = $ftp_drawing_frame_url.'/'.$drawing_frame_val;
                $drawing_frame_path = pathinfo($drawing_frame_url);
                $size = pathinfo($drawing_frame_path['dirname']);
                $inout_xml.= '<snapshot path="'.$drawing_frame_path['dirname'].'" size="'.strtolower($size['basename']).'" interval="'.$this->data_model['nns_drawing_rule'].'" />';
            }
        }
        $inout_xml.=        '</task>';
        $inout_xml.=    '</body>';
        $inout_xml.='</message>';
        $content_length = strlen($inout_xml);
        $arr_header = array(
            "Content-type: text/xml;charset=\"utf-8\"",
            "Accept: text/xml",
            "Cache-Control: no-cache",
            "Pragma: no-cache",
            "SOAPAction: \"run\"",
            "Content-Length: {$content_length}",
        );
        $result = $this->_execute_curl($this->request_url['live'],$this->curl_way, $inout_xml,$arr_header);
        if($result['ret'] !=0)
        {
            $log_file = $this->make_file_log($inout_xml, '');
            $this->make_file_encode_log($this->data_queue['nns_id'],"转码请求失败，描述[{$result['reason']}]",0,1,$log_file['request'],$log_file['notify']);
            nl_file_encode::edit($this->obj_dc, array('nns_state'=>2), $this->data_queue['nns_id']);
            return $this->__return_data(1,$result['reason']);
        }
        $message_content = (isset($result['data_info']) && strlen($result['data_info'])>0) ? $result['data_info'] : '';
        $log_file = $this->make_file_log($inout_xml, $message_content);
        if(!$this->is_xml($message_content))
        {
            $this->make_file_encode_log($this->data_queue['nns_id'],"转码返回的值非xml",0,1,$log_file['request'],$log_file['notify']);
            nl_file_encode::edit($this->obj_dc, array('nns_state'=>2), $this->data_queue['nns_id']);
            return $this->__return_data(1,"转码返回的值非xml");
        }
        $result_ex = json_decode(json_encode(@simplexml_load_string($message_content)),true);
        $description = isset($result_ex['body']['result']['@attributes']['description']) ? $result_ex['body']['result']['@attributes']['description'] : '';
        if(isset($result_ex['body']['result']['@attributes']['code']) && $result_ex['body']['result']['@attributes']['code'] =='1')
        {
            $result = $this->make_file_encode_log($this->data_queue['nns_id'],"请求转码成功",0,0,$log_file['request'],$log_file['notify']);
            nl_file_encode::edit($this->obj_dc, array('nns_state'=>1), $this->data_queue['nns_id']);
            return $this->__return_data(0,$description);
        }
        $this->make_file_encode_log($this->data_queue['nns_id'],"请求转码失败",0,1,$log_file['request'],$log_file['notify']);
        nl_file_encode::edit($this->obj_dc, array('nns_state'=>1), $this->data_queue['nns_id']);
        return $this->__return_data(1,$description);
    }
    
    /**
     * 直播转点播
     */
    public function set_task_live_to_media()
    {
        if(strlen($this->request_url['video']) <1)
        {
            return $this->__return_data(1,'转码请求地址request_url配置为空:'.$this->request_url);
        }
        if(!isset($this->arr_sp_config[$this->sp_id]['nns_config']['clip_file_addr_output']) || strlen($this->arr_sp_config[$this->sp_id]['nns_config']['clip_file_addr_output']) <1)
        {
            return $this->__return_data(1,'转码文件输入FTP配置为空:'.$this->arr_sp_config[$this->sp_id]['nns_config']['clip_file_addr_output']);
        }
        if(!isset($this->encode_file_url['media']) || strlen($this->encode_file_url['media']) <1)
        {
            return $this->__return_data(1,'转码文件输出为空:'.$this->encode_file_url['media']);
        }
        $result_media = nl_vod_media_v2::query_by_id($this->obj_dc, $this->data_queue['nns_in_media_id']);
        if($result_media['ret'] !=0)
        {
            return $result_media;
        }
        if(!isset($result_media['data_info']['nns_ext_info']) || strlen($result_media['data_info']['nns_ext_info'])<1 || !$this->is_json($result_media['data_info']['nns_ext_info']))
        {
            return $this->__return_data(1,'查询的原始片源没有片源路径');
        }
        $nns_ext_info = json_decode($result_media['data_info']['nns_ext_info'],true);
        if(!isset($nns_ext_info['path']) || strlen($nns_ext_info['path'])<1)
        {
            return $this->__return_data(1,'查询的原始片源没有片源路径path');
        }
        $ftp_url = trim(rtrim(rtrim($this->arr_sp_config[$this->sp_id]['nns_config']['clip_file_addr_output'],'/'),'\\'));
        $in_file_url = trim(ltrim(ltrim($nns_ext_info['path'],'/'),'\\'));
        $out_file_url = trim(ltrim(ltrim($this->encode_file_url['media'],'/'),'\\'));
        
        
        #TODO 直播转点播  请求 MSP
        $ftp_in = $ftp_url.'/'.$in_file_url;
        $in_arr_file_name = pathinfo($ftp_in);
         
        $ftp_out = $ftp_url.'/'.$out_file_url;
        $out_arr_file_name = pathinfo($ftp_out);
        
        $this->arr_video_params['max_v_bitrate'] = $this->arr_video_params['v_bitrate'] = (int)$this->data_model['nns_output_bitrate'] > 0 ? (int)$this->data_model['nns_output_bitrate']*1024 : 4000*1024;
        $inout_xml ='<?xml version="1.0" encoding="UTF-8"?>';
        $inout_xml.='<message module="xCoder" version="1.0.1.1730">';
        $inout_xml.=   '<header action="REQUEST" command="TASK_ASSIGN" />';
        $inout_xml.=   '<body>';
        $inout_xml.=       '<task id="'.$this->data_queue['nns_integer_id'].'">';
        $inout_xml.=           '<input>';
        $inout_xml.=               '<i_path>'.$ftp_in.'</i_path>';
        $inout_xml.=               '<i_file_fmt>'.$in_arr_file_name['extension'].'</i_file_fmt>';
        $inout_xml.=           '</input>';
        $inout_xml.=           '<output>';
        $inout_xml.=               '<o_path>'.$ftp_out.'</o_path>';
        $inout_xml.=               '<system_params>';
        $inout_xml.=                   '<file_format>'.$out_arr_file_name['extension'].'</file_format>';
        $inout_xml.=                   '<drm_encryption_flag>disable</drm_encryption_flag>';
        $inout_xml.=                   '<hls_segmenter>disable</hls_segmenter>';
        
        if(isset($this->encode_file_url['drawing_frame']) && is_array($this->encode_file_url['drawing_frame']) && !empty($this->encode_file_url['drawing_frame']))
        {
            if(!isset($this->arr_sp_config[$this->sp_id]['nns_config']['drawing_frame_addr_output']) || strlen($this->arr_sp_config[$this->sp_id]['nns_config']['drawing_frame_addr_output']) <1)
            {
                return $this->__return_data(1,'抽帧图片img_ftp输入FTP配置为空:'.$this->arr_sp_config[$this->sp_id]['nns_config']['img_ftp']);
            }
            $ftp_drawing_frame_url = trim(rtrim(rtrim($this->arr_sp_config[$this->sp_id]['nns_config']['drawing_frame_addr_output'],'/'),'\\'));
            $this->data_model['nns_drawing_rule'] = (int)$this->data_model['nns_drawing_rule'] > 0 ? (int)$this->data_model['nns_drawing_rule'] : 20;
            $i = 0;
            foreach ($this->encode_file_url['drawing_frame'] as $drawing_frame_val)
            {
                $i++;
                if($i > 1)
                {
                    break;
                }
                $drawing_frame_val = trim(ltrim(ltrim($drawing_frame_val,'/'),'\\'));
                if(strlen($drawing_frame_val) <1)
                {
                    continue;
                }
                $drawing_frame_url = $ftp_drawing_frame_url.'/'.$drawing_frame_val;
                $drawing_frame_path = pathinfo($drawing_frame_url);
                $size = pathinfo($drawing_frame_path['dirname']);
                 
                $inout_xml.=                   '<snapshot>';
                $inout_xml.=                       '<snapshot_flag>enable</snapshot_flag>';
                $inout_xml.=                       '<snapshot_path>'.$drawing_frame_path['dirname'].'</snapshot_path>';
                $inout_xml.=                       '<snapshot_size>'.strtolower($size['basename']).'</snapshot_size>';
                $inout_xml.=                       '<snapshot_interval>'.$this->data_model['nns_drawing_rule'].'</snapshot_interval>';
                $inout_xml.=                   '</snapshot>';
            }
        }
// 	    else
// 	    {
//     	    $inout_xml.=                   '<snapshot>';
//     	    $inout_xml.=                       '<snapshot_flag>disable</snapshot_flag>';
//     	    $inout_xml.=                   '</snapshot>';
// 	    }
        $inout_xml.=               '</system_params>';
        $inout_xml.=               '<video_params>';
        foreach ($this->arr_video_params as $video_key=>$video_val)
        {
            if(isset($this->data_model['nns_video_config'][$video_key]['value']) && strlen($this->data_model['nns_video_config'][$video_key]['value']) >0)
            {
                $video_val = $this->data_model['nns_video_config'][$video_key]['value'];
            }
            $inout_xml.=    '<'.$video_key.'>'.$video_val.'</'.$video_key.'>';
        }
        $temp_arr_video_params = array_keys($this->arr_video_params);
        if(is_array($this->data_model['nns_video_config']) && !empty($this->data_model['nns_video_config']))
        {
            foreach ($this->data_model['nns_video_config'] as $video_model_key=>$video_model_val)
            {
                if(!in_array($video_model_key, $temp_arr_video_params) && isset($video_model_val['value']) && strlen($video_model_val['value']) >0)
                {
                    $inout_xml.=    '<'.$video_model_key.'>'.$video_model_val['value'].'</'.$video_model_key.'>';
                }
            }
        }
        $inout_xml.=               '</video_params>';
        $inout_xml.=               '<audio_params>';
        
        foreach ($this->arr_audio_params as $audio_key=>$audio_val)
        {
            if(isset($this->data_model['nns_audio_config'][$audio_key]['value']) && strlen($this->data_model['nns_audio_config'][$audio_key]['value']) >0)
            {
                $audio_val = $this->data_model['nns_audio_config'][$audio_key]['value'];
            }
            $inout_xml.=    '<'.$audio_key.'>'.$audio_val.'</'.$audio_key.'>';
        }

        $temp_arr_audio_params = array_keys($this->arr_audio_params);
        if(is_array($this->data_model['nns_audio_config']) && !empty($this->data_model['nns_audio_config']))
        {
            foreach ($this->data_model['nns_audio_config'] as $audio_model_key=>$audio_model_val)
            {
                if(!in_array($audio_model_key, $temp_arr_audio_params) && isset($audio_model_val['value']) && strlen($audio_model_val['value']) >0)
                {
                    $inout_xml.=    '<'.$audio_model_key.'>'.$audio_model_val['value'].'</'.$audio_model_key.'>';
                }
            }
        }
        $inout_xml.=               '</audio_params>';
        $inout_xml.=               '<subtitle_params></subtitle_params>';
        $inout_xml.=           '</output>';
        $inout_xml.=       '</task>';
        $inout_xml.=   '</body>';
        $inout_xml.='</message>';
        $content_length = strlen($inout_xml);
        $arr_header = array(
            "Content-type: text/xml;charset=\"utf-8\"",
            "Accept: text/xml",
            "Cache-Control: no-cache",
            "Pragma: no-cache",
            "SOAPAction: \"run\"",
            "Content-Length: {$content_length}",
        );
        $result = $this->_execute_curl($this->request_url['video'],$this->curl_way, $inout_xml,$arr_header);
        if($result['ret'] !=0)
        {
            $log_file = $this->make_file_log($inout_xml, '');
            $this->make_file_encode_log($this->data_queue['nns_id'],"转码请求失败，描述[{$result['reason']}]",0,1,$log_file['request'],$log_file['notify']);
            nl_file_encode::edit($this->obj_dc, array('nns_state'=>2), $this->data_queue['nns_id']);
            return $this->__return_data(1,$result['reason']);
        }
        $message_content = (isset($result['data_info']) && strlen($result['data_info'])>0) ? $result['data_info'] : '';
        $log_file = $this->make_file_log($inout_xml, $message_content);
        if(!$this->is_xml($message_content))
        {
            $this->make_file_encode_log($this->data_queue['nns_id'],"转码返回的值非xml",0,1,$log_file['request'],$log_file['notify']);
            nl_file_encode::edit($this->obj_dc, array('nns_state'=>2), $this->data_queue['nns_id']);
            return $this->__return_data(1,"转码返回的值非xml");
        }
        $result_ex = json_decode(json_encode(@simplexml_load_string($message_content)),true);
        $description = isset($result_ex['body']['result']['@attributes']['description']) ? $result_ex['body']['result']['@attributes']['description'] : '';
        if(isset($result_ex['body']['result']['@attributes']['code']) && $result_ex['body']['result']['@attributes']['code'] =='1')
        {
            $result = $this->make_file_encode_log($this->data_queue['nns_id'],"请求转码成功",0,0,$log_file['request'],$log_file['notify']);
            nl_file_encode::edit($this->obj_dc, array('nns_state'=>1), $this->data_queue['nns_id']);
            return $this->__return_data(0,$description);
        }
        $this->make_file_encode_log($this->data_queue['nns_id'],"请求转码失败",0,1,$log_file['request'],$log_file['notify']);
        nl_file_encode::edit($this->obj_dc, array('nns_state'=>1), $this->data_queue['nns_id']);
        return $this->__return_data(1,$description);
    }
    
	/**
	 * 上报点播转码数据
	 */
	public function set_task_media()
	{
	    if(strlen($this->request_url['video']) <1)
	    {
	        return $this->__return_data(1,'转码请求地址request_url配置为空:'.$this->request_url);
	    }
	    if(!isset($this->arr_sp_config[$this->sp_id]['nns_config']['clip_file_addr_output']) || strlen($this->arr_sp_config[$this->sp_id]['nns_config']['clip_file_addr_output']) <1)
	    {
	        return $this->__return_data(1,'转码文件输入FTP配置为空:'.$this->arr_sp_config[$this->sp_id]['nns_config']['clip_file_addr_output']);
	    }
	    if(!isset($this->encode_file_url['media']['in']) || strlen($this->encode_file_url['media']['in']) <1)
	    {
	        return $this->__return_data(1,'转码文件输入文件为空:'.$this->encode_file_url['media']);
	    }
	    if(!isset($this->encode_file_url['media']['out']) || strlen($this->encode_file_url['media']['out']) <1)
	    {
	        return $this->__return_data(1,'转码文件输出文件为空:'.$this->encode_file_url['media']);
	    }
	    $result_media = nl_vod_media_v2::query_by_id($this->obj_dc, $this->data_queue['nns_in_media_id']);
	    if($result_media['ret'] !=0)
	    {
	        return $result_media;
	    }
	    if(!isset($result_media['data_info']['nns_ext_info']) || strlen($result_media['data_info']['nns_ext_info'])<1 || !$this->is_json($result_media['data_info']['nns_ext_info']))
	    {
	        if(isset($this->arr_sp_config[$this->sp_id]['nns_config']['clip_file_encode_model'])&& $this->arr_sp_config[$this->sp_id]['nns_config']['clip_file_encode_model'] == '2' && strlen($result_media['data_info']['nns_url']) >0)
	        {
	            $nns_ext_info['path'] = $nns_ext_info['url'] = $result_media['data_info']['nns_url'];
	        }
	        else
	        {
	           return $this->__return_data(1,'查询的原始片源没有片源路径');
	        }
	    }
	    else
	    {
	       $nns_ext_info = json_decode($result_media['data_info']['nns_ext_info'],true);
	    }
	    if(!isset($nns_ext_info['path']) || strlen($nns_ext_info['path'])<1)
	    {
	        return $this->__return_data(1,'查询的原始片源没有片源路径path');
	    }
	    $ftp_url = trim(rtrim(rtrim($this->arr_sp_config[$this->sp_id]['nns_config']['clip_file_addr_output'],'/'),'\\'));
	    $in_file_url = trim(ltrim(ltrim($this->encode_file_url['media']['in'],'/'),'\\'));
	    $out_file_url = trim(ltrim(ltrim($this->encode_file_url['media']['out'],'/'),'\\'));
	    
	    $ftp_in = $ftp_url.'/'.$in_file_url;
	    $in_arr_file_name = pathinfo($ftp_in);
	    
	    $ftp_out = $ftp_url.'/'.$out_file_url;
	    $out_arr_file_name = pathinfo($ftp_out);
	    
	    if(strpos($ftp_out, 'ftp://') !== false)
	    {
	        $obj_ftp = new nl_ftp(null,null,null,21,90,false,$ftp_out);
	        $temp_data_info  = $obj_ftp->check_file_exsist($obj_ftp->path);
	        if($temp_data_info['ret'] == 0 && $temp_data_info['data_info'] >0)
	        {
	            $obj_ftp->delete_file($obj_ftp->path);
	        }
	    }
	    
	    $this->arr_video_params['max_v_bitrate'] = $this->arr_video_params['v_bitrate'] = (int)$this->data_model['nns_output_bitrate'] > 0 ? (int)$this->data_model['nns_output_bitrate']*1024 : 4000*1024;
	    
	    $inout_xml ='<?xml version="1.0" encoding="UTF-8"?>';
	    $inout_xml.='<message module="xCoder" version="1.0.1.1730">';
	    $inout_xml.=   '<header action="REQUEST" command="TASK_ASSIGN" />';
	    $inout_xml.=   '<body>';
	    $inout_xml.=       '<task id="'.$this->data_queue['nns_integer_id'].'">';
	    $inout_xml.=           '<input>';
	    $inout_xml.=               '<i_path>'.$ftp_in.'</i_path>';
	    $inout_xml.=               '<i_file_fmt>'.$in_arr_file_name['extension'].'</i_file_fmt>';
	    $inout_xml.=           '</input>';
	    $inout_xml.=           '<output>';
	    $inout_xml.=               '<o_path>'.$ftp_out.'</o_path>';
	    $inout_xml.=               '<system_params>';
	    $inout_xml.=                   '<file_format>'.$out_arr_file_name['extension'].'</file_format>';
	    $inout_xml.=                   '<drm_encryption_flag>disable</drm_encryption_flag>';
	    $inout_xml.=                   '<hls_segmenter>disable</hls_segmenter>';

	    if(isset($this->encode_file_url['drawing_frame']) && is_array($this->encode_file_url['drawing_frame']) && !empty($this->encode_file_url['drawing_frame']))
	    {
	        if(!isset($this->arr_sp_config[$this->sp_id]['nns_config']['drawing_frame_addr_output']) || strlen($this->arr_sp_config[$this->sp_id]['nns_config']['drawing_frame_addr_output']) <1)
	        {
	            return $this->__return_data(1,'抽帧图片img_ftp输入FTP配置为空:'.$this->arr_sp_config[$this->sp_id]['nns_config']['img_ftp']);
	        }
	        $ftp_drawing_frame_url = trim(rtrim(rtrim($this->arr_sp_config[$this->sp_id]['nns_config']['drawing_frame_addr_output'],'/'),'\\'));
	        $this->data_model['nns_drawing_rule'] = (int)$this->data_model['nns_drawing_rule'] > 0 ? (int)$this->data_model['nns_drawing_rule'] : 20;
	        $i = 0;
	        foreach ($this->encode_file_url['drawing_frame'] as $drawing_frame_val)
	        {
	            $i++;
	            if($i > 1)
	            {
	                break;
	            }
	            $drawing_frame_val = trim(ltrim(ltrim($drawing_frame_val,'/'),'\\'));
	            if(strlen($drawing_frame_val) <1)
	            {
	                continue;
	            }
	            $drawing_frame_url = $ftp_drawing_frame_url.'/'.$drawing_frame_val;
	            $drawing_frame_path = pathinfo($drawing_frame_url);
	            $size = pathinfo($drawing_frame_path['dirname']);
	            
	            $inout_xml.=                   '<snapshot>';
	            $inout_xml.=                       '<snapshot_flag>enable</snapshot_flag>';
	            $inout_xml.=                       '<snapshot_path>'.$drawing_frame_path['dirname'].'</snapshot_path>';
	            $inout_xml.=                       '<snapshot_size>'.strtolower($size['basename']).'</snapshot_size>';
	            $inout_xml.=                       '<snapshot_interval>'.$this->data_model['nns_drawing_rule'].'</snapshot_interval>';
	            $inout_xml.=                   '</snapshot>';
	        }
	    }
// 	    else
// 	    {
//     	    $inout_xml.=                   '<snapshot>';
//     	    $inout_xml.=                       '<snapshot_flag>disable</snapshot_flag>';
//     	    $inout_xml.=                   '</snapshot>';
// 	    }
	    $inout_xml.=               '</system_params>';
	    $inout_xml.=               '<video_params>';
	    foreach ($this->arr_video_params as $video_key=>$video_val)
        {
            if(isset($this->data_model['nns_video_config'][$video_key]['value']) && strlen($this->data_model['nns_video_config'][$video_key]['value']) >0)
            {
                $video_val = $this->data_model['nns_video_config'][$video_key]['value'];
            }
            $inout_xml.=    '<'.$video_key.'>'.$video_val.'</'.$video_key.'>';
        }
        $temp_arr_video_params = array_keys($this->arr_video_params);
        if(is_array($this->data_model['nns_video_config']) && !empty($this->data_model['nns_video_config']))
        {
            foreach ($this->data_model['nns_video_config'] as $video_model_key=>$video_model_val)
            {
                if(!in_array($video_model_key, $temp_arr_video_params) && isset($video_model_val['value']) && strlen($video_model_val['value']) >0)
                {
                    $inout_xml.=    '<'.$video_model_key.'>'.$video_model_val['value'].'</'.$video_model_key.'>';
                }
            }
        }
	    $inout_xml.=               '</video_params>';
	    $inout_xml.=               '<audio_params>';
	    foreach ($this->arr_audio_params as $audio_key=>$audio_val)
        {
            if(isset($this->data_model['nns_audio_config'][$audio_key]['value']) && strlen($this->data_model['nns_audio_config'][$audio_key]['value']) >0)
            {
                $audio_val = $this->data_model['nns_audio_config'][$audio_key]['value'];
            }
            $inout_xml.=    '<'.$audio_key.'>'.$audio_val.'</'.$audio_key.'>';
        }

        $temp_arr_audio_params = array_keys($this->arr_audio_params);
        if(is_array($this->data_model['nns_audio_config']) && !empty($this->data_model['nns_audio_config']))
        {
            foreach ($this->data_model['nns_audio_config'] as $audio_model_key=>$audio_model_val)
            {
                if(!in_array($audio_model_key, $temp_arr_audio_params) && isset($audio_model_val['value']) && strlen($audio_model_val['value']) >0)
                {
                    $inout_xml.=    '<'.$audio_model_key.'>'.$audio_model_val['value'].'</'.$audio_model_key.'>';
                }
            }
        }
	    $inout_xml.=               '</audio_params>';
	    $inout_xml.=               '<subtitle_params></subtitle_params>';
	    $inout_xml.=           '</output>';
	    $inout_xml.=       '</task>';
	    $inout_xml.=   '</body>';
	    $inout_xml.='</message>';
	    $content_length = strlen($inout_xml);
	    $arr_header = array(
	        "Content-type: text/xml;charset=\"utf-8\"",
	        "Accept: text/xml",
	        "Cache-Control: no-cache",
	        "Pragma: no-cache",
	        "SOAPAction: \"run\"",
	        "Content-Length: {$content_length}",
	    );
	    $result = $this->_execute_curl($this->request_url['video'],$this->curl_way, $inout_xml,$arr_header);
        if($result['ret'] !=0)
	    {
	        $log_file = $this->make_file_log($inout_xml, '');
            $this->make_file_encode_log($this->data_queue['nns_id'],"转码请求失败，描述[{$result['reason']}]",0,1,$log_file['request'],$log_file['notify']);
            nl_file_encode::edit($this->obj_dc, array('nns_state'=>2,'nns_again'=>$this->data_queue['nns_again']+1), $this->data_queue['nns_id']);
	        return $this->__return_data(1,$result['reason']);
	    }
	    $message_content = (isset($result['data_info']) && strlen($result['data_info'])>0) ? $result['data_info'] : '';
        $log_file = $this->make_file_log($inout_xml, $message_content);
	    if(!$this->is_xml($message_content))
	    {
	        $this->make_file_encode_log($this->data_queue['nns_id'],"转码返回的值非xml",0,1,$log_file['request'],$log_file['notify']);
	        nl_file_encode::edit($this->obj_dc, array('nns_state'=>2,'nns_again'=>$this->data_queue['nns_again']+1), $this->data_queue['nns_id']);
	        return $this->__return_data(1,"转码返回的值非xml");
	    }
	    $result_ex = json_decode(json_encode(@simplexml_load_string($message_content)),true);
	    $description = isset($result_ex['body']['result']['@attributes']['description']) ? $result_ex['body']['result']['@attributes']['description'] : '';
	    if(isset($result_ex['body']['result']['@attributes']['code']) && $result_ex['body']['result']['@attributes']['code'] =='1')
	    {
	        $result = $this->make_file_encode_log($this->data_queue['nns_id'],"请求转码成功",0,0,$log_file['request'],$log_file['notify']);
	        nl_file_encode::edit($this->obj_dc, array('nns_state'=>1,'nns_loadbalance_id'=>$this->arr_params['nns_id']), $this->data_queue['nns_id']);
	        return $this->__return_data(0,$description);
	    }
        $this->make_file_encode_log($this->data_queue['nns_id'],"请求转码失败",0,1,$log_file['request'],$log_file['notify']);
        nl_file_encode::edit($this->obj_dc, array('nns_state'=>2,'nns_again'=>$this->data_queue['nns_again']+1), $this->data_queue['nns_id']);
        return $this->__return_data(1,$description);
	}
	
	/**
	 * 终止转码数据
	 */
	public function cancel_task($task_id)
	{
	    $inout_xml ='<?xml version="1.0" encoding="utf-8"?>';
	    $inout_xml.='<message module="xCoder" version="1.0">';
	    $inout_xml.=   '<header action="REQUEST" command="TASK_CANCEL" />';
	    $inout_xml.=   '<body>';
	    $inout_xml.=   '<task id="'.$task_id.'" />';
	    $inout_xml.=   '</body>';
	    $inout_xml.='</message>';
	    $content_length = strlen($inout_xml);
	    $arr_header = array(
	        "Content-type: text/xml;charset=\"utf-8\"",
	        "Accept: text/xml",
	        "Cache-Control: no-cache",
	        "Pragma: no-cache",
	        "SOAPAction: \"run\"",
	        "Content-Length: {$content_length}",
	    );
	    $result = $this->_execute_curl($this->request_url['video'],$this->curl_way, $inout_xml,$arr_header);
	    if($result['ret'] !=0)
	    {
	        return $result;
	    }
	    $message_content = (isset($result['data_info']) && strlen($result['data_info'])>0) ? $result['data_info'] : '';
	    if(!$this->is_xml($message_content))
	    {
	        return $this->__return_data(1,"反馈的数据非xml");
	    }
	    //解析下载的XML
	    $dom = new DOMDocument('1.0', 'utf-8');
	    $dom->loadXML($message_content);
	    $task = $dom->getElementsByTagName('result');
    	if($task->length <1)
        {
            return $this->__return_data(1,"无队列状态查询到",array('nns_request_state'=>0,'nns_notify_state'=>1,'nns_request_content'=>$inout_xml,'nns_notify_content'=>$message_content));
        }
        $nns_request_content = trim($inout_xml);
        $nns_notify_content = trim($message_content);
        $log_file = $this->make_file_log($nns_request_content, $nns_notify_content);
        $temp_task = null;
	    foreach ($task as $task_val)
        {
            $id = $task_val->getAttribute('task');
            $status = $task_val->getAttribute('code');
            $cause = $task_val->getAttribute('description');
            if(strlen($id) <1 || strlen($status) <1)
            {
                continue;
            }
            $result_exsist = nl_file_encode::query_by_integer_id($this->obj_dc, $id);
            if($result_exsist['ret'] !=0)
            {
                return $result_exsist;
            }
            if(!isset($result_exsist['data_info']) || !is_array($result_exsist['data_info']) || empty($result_exsist['data_info']))
            {
                $temp_task[]=$id;
                continue;
            }
            $result_exsist = $result_exsist['data_info'];
            if($status == '1')
            {
                $this->make_file_encode_log($result_exsist['nns_id'],"转码队列任务终止成功，描述[{$cause}]",0,0,$log_file['request'],$log_file['notify']);
            }
            else
            {
                $this->make_file_encode_log($result_exsist['nns_id'],"转码队列任务终止失败，描述[{$cause}]",0,1,$log_file['request'],$log_file['notify']);
            }
        }
        return $this->__return_data(0,'ok',$temp_task);
	}
	
	/**
	 * 删除转码数据
	 */
	public function del_task($id=NULL)
	{
	    $inout_xml ='<?xml version="1.0" encoding="utf-8"?>';
	    $inout_xml.='<message module="xCoder" version="1.0">';
	    $inout_xml.=   '<header action="REQUEST" command="TASK_DELETE" />';
	    $inout_xml.=   '<body>';
	    if(strlen($id) >0)
	    {
	        $inout_xml.=   '<task id="'.$id.'" />';
	    }
	    else
	    {
	        $inout_xml.=   '<task id="" />';
	    }
	    $inout_xml.=   '</body>';
	    $inout_xml.='</message>';
	    $content_length = strlen($inout_xml);
	    $arr_header = array(
	        "Content-type: text/xml;charset=\"utf-8\"",
	        "Accept: text/xml",
	        "Cache-Control: no-cache",
	        "Pragma: no-cache",
	        "SOAPAction: \"run\"",
	        "Content-Length: {$content_length}",
	    );
	    $result = $this->_execute_curl($this->request_url['video'],$this->curl_way, $inout_xml,$arr_header);
	    if($result['ret'] !=0)
	    {
	        return $result;
	    }
	    $message_content = (isset($result['data_info']) && strlen($result['data_info'])>0) ? $result['data_info'] : '';
	    if(!$this->is_xml($message_content))
	    {
	        return $this->__return_data(1,"反馈的数据非xml");
	    }
	    //解析下载的XML
	    $dom = new DOMDocument('1.0', 'utf-8');
	    $dom->loadXML($message_content);
	    $task = $dom->getElementsByTagName('result');
    	if($task->length <1)
        {
            return $this->__return_data(1,"无队列状态查询到",array('nns_request_state'=>0,'nns_notify_state'=>1,'nns_request_content'=>$inout_xml,'nns_notify_content'=>$message_content));
        }
        $nns_request_content = trim($inout_xml);
        $nns_notify_content = trim($message_content);
        $log_file = $this->make_file_log($nns_request_content, $nns_notify_content);
        $temp_task = null;
	    foreach ($task as $task_val)
        {
            $id = $task_val->getAttribute('task');
            $status = $task_val->getAttribute('code');
            $cause = $task_val->getAttribute('description');
            if(strlen($id) <1 || strlen($status) <1)
            {
                continue;
            }
            $result_exsist = nl_file_encode::query_by_integer_id($this->obj_dc, $id);
            if($result_exsist['ret'] !=0)
            {
                return $result_exsist;
            }
            if(!isset($result_exsist['data_info']) || !is_array($result_exsist['data_info']) || empty($result_exsist['data_info']))
            {
                $temp_task[]=$id;
                continue;
            }
            $result_exsist = $result_exsist['data_info'];
            if($status == '1')
            {
                $this->make_file_encode_log($result_exsist['nns_id'],"转码队列删除成功，描述[{$cause}]",0,0,$log_file['request'],$log_file['notify']);
            }
            else
            {
                $this->make_file_encode_log($result_exsist['nns_id'],"转码队列删除失败，描述[{$cause}]",0,1,$log_file['request'],$log_file['notify']);
            }
        }
        return $this->__return_data(0,'ok',$temp_task);
	}
	
	public function debug_data()
	{
	    $arr_url = array(
            '59e0648828e85ed01473334264162030'=>'http://172.16.187.202:1080/other',
            '59e064a413e86c0dcfd457a799baaf21'=>'http://172.16.187.203:1080/other',
            '59e064c324b468d896f01a0813903375'=>'http://172.16.187.204:1080/other',
            '59e064dccb4130224c3975e0e5bcc8fd'=>'http://172.16.187.205:1080/other',
            '59e064f626ce8f492cb9b989953e7fa8'=>'http://172.16.187.206:1080/other',
	    );
	    foreach ($arr_url as $key=>$val)
	    {
	        $inout_xml ='<?xml version="1.0" encoding="UTF-8"?>';
	        $inout_xml.='<message module="xCoder" version="1.0">';
	        $inout_xml.=   '<header action="REQUEST" command="MACHINE_STATUS_REPORT" />';
	        $inout_xml.=   '<body></body>';
	        $inout_xml.='</message>';
	        $content_length = strlen($inout_xml);
	        $arr_header = array(
	            "Content-type: text/xml;charset=\"utf-8\"",
	            "Accept: text/xml",
	            "Cache-Control: no-cache",
	            "Pragma: no-cache",
	            "SOAPAction: \"run\"",
	            "Content-Length: {$content_length}",
	        );
	        $result = $this->_execute_curl($val,$this->curl_way, $inout_xml,$arr_header);
	        if($result['ret'] !=0)
	        {
	            return $result;
	        }
	        $message_content = (isset($result['data_info']) && strlen($result['data_info'])>0) ? $result['data_info'] : '';
	        if(!$this->is_xml($message_content))
	        {
	            return $this->__return_data(1,"反馈的数据非xml",array('nns_request_state'=>0,'nns_notify_state'=>1,'nns_request_content'=>$inout_xml,'nns_notify_content'=>$message_content));
	        }
	        //解析下载的XML
	        $dom = new DOMDocument('1.0', 'utf-8');
	        $dom->loadXML($message_content);
	        $task = $dom->getElementsByTagName('task');
	        if($task->length <1)
	        {
	            return $this->__return_data(1,"无队列状态查询到",array('nns_request_state'=>0,'nns_notify_state'=>1,'nns_request_content'=>$inout_xml,'nns_notify_content'=>$message_content));
	        }
	        $nns_request_content = trim($inout_xml);
	        $nns_notify_content = trim($message_content);
	        $log_file = $this->make_file_log($nns_request_content, $nns_notify_content);
	        $temp_task = null;
	        foreach ($task as $task_val)
	        {
	            $id = $task_val->getAttribute('id');
	            if(strlen($id) <1)
	            {
	                continue;
	            }
	            $sql = "update nns_file_encode set nns_loadbalance_id='{$key}' where nns_integer_id='{$id}'";
	            nl_execute_by_db($sql, $this->obj_dc->db());
	        }
	    }
	}
	
	
	/**
	 * 获取转码状态
	 */
	public function get_task_state()
	{
	    $this->init(0);
	    if(strlen($this->request_url['video']) <1)
	    {
	        return $this->__return_data(1,'转码请求地址request_url配置为空:'.$this->request_url);
	    }
		$inout_xml ='<?xml version="1.0" encoding="UTF-8"?>';
	    $inout_xml.='<message module="xCoder" version="1.0">';
	    $inout_xml.=   '<header action="REQUEST" command="MACHINE_STATUS_REPORT" />';
	    $inout_xml.=   '<body></body>';
	    $inout_xml.='</message>';
	    $content_length = strlen($inout_xml);
	    $arr_header = array(
	        "Content-type: text/xml;charset=\"utf-8\"",
	        "Accept: text/xml",
	        "Cache-Control: no-cache",
	        "Pragma: no-cache",
	        "SOAPAction: \"run\"",
	        "Content-Length: {$content_length}",
	    );
	    $result = $this->_execute_curl($this->request_url['video'],$this->curl_way, $inout_xml,$arr_header);
	    if($result['ret'] !=0)
	    {
	        return $result;
	    }
	    $message_content = (isset($result['data_info']) && strlen($result['data_info'])>0) ? $result['data_info'] : '';
	    if(!$this->is_xml($message_content))
	    {
	        return $this->__return_data(1,"反馈的数据非xml",array('nns_request_state'=>0,'nns_notify_state'=>1,'nns_request_content'=>$inout_xml,'nns_notify_content'=>$message_content));
	    }
	    //解析下载的XML
	    $dom = new DOMDocument('1.0', 'utf-8');
	    $dom->loadXML($message_content);
	    $task = $dom->getElementsByTagName('task');
    	if($task->length <1)
        {
            return $this->__return_data(1,"无队列状态查询到",array('nns_request_state'=>0,'nns_notify_state'=>1,'nns_request_content'=>$inout_xml,'nns_notify_content'=>$message_content));
        }
        $nns_request_content = trim($inout_xml);
        $nns_notify_content = trim($message_content);
        $log_file = $this->make_file_log($nns_request_content, $nns_notify_content);
        $temp_task = null;
	    foreach ($task as $task_val)
        {
            $id = $task_val->getAttribute('id');
            $status = $task_val->getAttribute('status');
            $cause = $task_val->getAttribute('cause');
            $progress = $task_val->getAttribute('progress');
            $progress = (strlen($progress) >0 && (int)$progress >0) ? $progress : 0;
            if(strlen($id) <1 || strlen($status) <1)
            {
                continue;
            }
            $result_exsist = nl_file_encode::query_by_integer_id($this->obj_dc, $id);
            if($result_exsist['ret'] !=0)
            {
                return $result_exsist;
            }
            if(!isset($result_exsist['data_info']) || !is_array($result_exsist['data_info']) || empty($result_exsist['data_info']))
            {
                $temp_task[]=$id;
                continue;
            }
            $result_exsist = $result_exsist['data_info'];
            if($status == '100')
            {
                $this->make_file_encode_log($result_exsist['nns_id'],"转码成功，描述[{$cause}]",0,0,$log_file['request'],$log_file['notify']);
                nl_file_encode::edit($this->obj_dc, array('nns_state'=>3,'nns_priority'=>0), $result_exsist['nns_id']);
                nl_op_queue::edit($this->obj_dc, array('nns_status'=>0), $result_exsist['nns_op_id']);
                $this->del_task($id);
            }
            else if($status == '90')
            {
                $this->make_file_encode_log($result_exsist['nns_id'],"转码失败，描述[{$cause}]",0,0,$log_file['request'],$log_file['notify']);
                $this->cancel_task($id);
                $this->del_task($id);
                nl_file_encode::edit($this->obj_dc, array('nns_state'=>0,'nns_again'=>$result_exsist['nns_again']+1), $result_exsist['nns_id']);
            }
            else
            {
                $this->make_file_encode_log($result_exsist['nns_id'],"正在转码，进度{$progress}%",0,0,$log_file['request'],$log_file['notify']);
            }
        }
        return $this->__return_data(0,'ok',$temp_task);
	}
	
	/**
	 * 生成日志文件
	 */
	public function make_file_log($nns_request_content='',$nns_notify_content='')
	{
	    $database_url = date("Ymd").'/'.date("H");
	    if(strlen($nns_notify_content)>0)
	    {
	        $dir_file = 'mgtv/file_encode/'.strtolower($this->sp_id).'/notify';
	        $nns_notify_content = $this->_make_log_file($nns_notify_content, $database_url,$dir_file);
	        $nns_notify_content = (isset($nns_notify_content['data_info']) && strlen($nns_notify_content['data_info'])>0) ? $nns_notify_content['data_info'] : '';
	    }
	    else
	    {
	        $nns_notify_content='';
	    }
	    if(strlen($nns_request_content)>0)
	    {
	        $dir_file = 'mgtv/file_encode/'.strtolower($this->sp_id).'/request';
	        $nns_request_content = $this->_make_log_file($nns_request_content, $database_url,$dir_file);
	        $nns_request_content = (isset($nns_request_content['data_info']) && strlen($nns_request_content['data_info'])>0) ? $nns_request_content['data_info'] : '';
	    }
	    else
	    {
	        $nns_request_content='';
	    }
	    return array(
	        'request'=>$nns_request_content,
	        'notify'=>$nns_notify_content,
	    );
	}
	
	/**
	 * 插入转码日志
	 * @param unknown $file_encode_id
	 * @param unknown $nns_request_state
	 * @param string $nns_request_state
	 * @param unknown $nns_notify_state
	 * @param string $nns_notify_content
	 * @param unknown $nns_desc
	 */
	public function make_file_encode_log($file_encode_id,$nns_desc,$nns_request_state=0,$nns_notify_state=0,$nns_request_content='',$nns_notify_content='')
	{
	    if(strlen($file_encode_id) <1)
	    {
	        return $this->__return_data(1,'file_encode_id 参数为空不生成转码日志');
	    }
	    $arr_params = array(
	        'nns_id'=>np_guid_rand('file_encode_log'),
	        'nns_file_encode_id'=>$file_encode_id,
	        'nns_desc'=>$nns_desc,
	        'nns_request_state'=>$nns_request_state,
	        'nns_notify_state'=>$nns_notify_state,
	        'nns_request_content'=>$nns_request_content,
	        'nns_notify_content'=>$nns_notify_content,
	    );
	    return nl_file_encode_log::add($this->obj_dc, $arr_params);
	}
}
